#include "FnTagging.h"

FnTagging::FnTagging(Mesh& _mesh)
: mesh_(_mesh)
{
}

FnTagging::~FnTagging(void)
{
}



void FnTagging::tagging(const std::string& _tag_filename, const std::string& _avm_filename)
{
  std::vector<OpenVolMesh::VertexHandle>   vhandles;
  std::vector<OpenVolMesh::HalffaceHandle> hfhandles;

  Mesh::VertexIter      v_it;
  Mesh::FaceIter        f_it;
  Mesh::CellIter        c_it;
  Mesh::FaceVertexIter  fv_it;
  Mesh::Point           p;
  
  OpenVolMesh::FPropHandleT<int>   fprop_index_;

  mesh().add_property(fprop_index_);

  FILE    *fp, *fp2;

  fp = fopen(_avm_filename.c_str(), "w");
  fp2 = fopen(_tag_filename.c_str(), "r");

  std::vector<int> tag_index;

  fprintf(fp, "# %d vertices\n", mesh().n_vertices());
  fprintf(fp, "# %d faces\n", mesh().n_faces());
  fprintf(fp, "# %d cells\n", mesh().n_cells());

  int tag_size, tag;

  fscanf(fp2, "%d", &tag_size);

  int nSides = 0;

  for(int i = 0; i < tag_size; i++){
	  fscanf(fp2, "%d", &tag);
	  tag_index.push_back(tag);
	  if (tag > nSides) nSides = tag;
  }
  nSides++;		//number of patches
  
	int cnt = 1;
  // ---------- write vertex position
  for (v_it=mesh().vertices_begin(); v_it!=mesh().vertices_end(); ++v_it)
  {
	p = mesh().point(v_it);
	fprintf(fp, "v %f %f %f\n", p[0], p[1], p[2]);    
  }

  std::vector<std::vector<Mesh::FaceHandle>> cube;
  cube.resize(nSides+1);

  int k = 0, i;

  for (f_it=mesh().faces_begin(); f_it!=mesh().faces_end(); ++f_it)
  {
	  if(k < tag_size){
		cube[tag_index[k]].push_back(f_it);
	  }
	  else{
		  cube[nSides].push_back(f_it);
	  }
	  k++;
  }


  int cnt2 = 1;
 Mesh::FaceHandle fh;

 for(i = 0; i <= nSides; i++){
	 //if(i == 0){
		// fprintf(fp, "g +y\n");
	 //}
	 //else if(i == 1){
		// fprintf(fp, "g -y\n");
	 //}
	 //else if(i == 2){
		// fprintf(fp, "g +z0\n");
	 //}
	 //else if(i == 3){
		// fprintf(fp, "g +x0\n");
	 //}
	 //else if(i == 4){
		// fprintf(fp, "g -z0\n");
	 //}
	 //else if(i == 5){
		// fprintf(fp, "g -x0\n");
	 //}
	 //else if(i == 6){
		// fprintf(fp, "g +z1\n");
	 //}
	 //else if(i == 7){
		// fprintf(fp, "g +x1\n");
	 //}
	 //else if(i == 8){
		// fprintf(fp, "g -z1\n");
	 //}
	 //else if(i == 9){
		// fprintf(fp, "g -x1\n");
	 //}
	 //else{
		// fprintf(fp, "g <noname>\n");
	 //}

	 if (i == nSides)
		 fprintf(fp, "g <noname>\n");
	 else
		fprintf(fp, "g %d\n", i);

	 for(k = 0; k < cube[i].size(); k++){ 
		 fh = cube[i].at(k);

		 fprintf(fp, "f");
		 mesh().property(fprop_index_, fh) = cnt2++;
		 for (fv_it=mesh().fv_iter(fh); fv_it; ++fv_it)
		 {
			 fprintf(fp, " %d", 1+fv_it.handle().idx());
		 }
		 fprintf(fp, "\n");
	 }
 }


    // -------------------- write cell data

  // ---------- write topology
 for (c_it=mesh().cells_begin(); c_it!=mesh().cells_end(); ++c_it)
    {
      get_hfhandles(c_it, hfhandles);
      
      fprintf(fp, "c");
      for (size_t j=0; j < hfhandles.size(); ++j)
      {
        int   face_idx;

        face_idx = hfhandles[j].idx()/2;
        face_idx = (hfhandles[j].idx()%2) ? mesh().property(fprop_index_, mesh().face_handle(hfhandles[j])) : -mesh().property(fprop_index_, mesh().face_handle(hfhandles[j]));
        
        fprintf(fp, " %d", face_idx);
      }
      fprintf(fp, "\n");
    }
  

  fclose(fp);
  fclose(fp2);

   mesh().remove_property(fprop_index_);

}